/**
 * Copyright ©2012-2018 HopeHaiyang Corporation, All Rights Reserved
 * http://www.wuhanhope.com
 */
package hope.platform.data.load;

import hope.platform.data.domain.type.FastDFSFile;
import lombok.extern.slf4j.Slf4j;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * class info
 *
 * @author hujia
 *         Create at 2018/8/9 13:53
 */
@Component
@Slf4j
public class FdfsClientLoader implements CommandLineRunner {

    private TrackerClient trackerClient;
    private TrackerServer trackerServer;
    private StorageServer storageServer;
    private StorageClient storageClient;

    @Override
    public void run(String... args) throws Exception {
        try {
            Properties properties=new Properties();
            properties.load(getClass().getClassLoader().getResourceAsStream("fdfs_client.properties"));
            ClientGlobal.initByProperties(properties);
            trackerClient = new TrackerClient();
            trackerServer = trackerClient.getConnection();
            storageServer = trackerClient.getStoreStorage(trackerServer);
        } catch (Exception e) {
            log.error("FastDFS client init failed", e);
            //todo 加入系统异常
        }
    }

    /**
     * 使用FastDFS提供的客户端storageClient来进行文件上传，最后将上传结果返回。
     *
     * @param file 上传文件信息（包含文件内容）
     */
    public String[] uploader(FastDFSFile file) {
        log.debug("File Name:" + file.getName() + "File Length:" + file.getContent().length);

        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author", file.getAuthor());
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String[] uploadResults = null;
        try {
            storageClient = new StorageClient(trackerServer, storageServer);
            uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
        } catch (IOException e) {
            log.warn("IO Exception when upload the file:" + file.getName(), e);
            //todo 加入系统异常
        } catch (Exception e) {
            log.warn("Non IO Exception when upload the file:" + file.getName(), e);
            //todo 加入系统异常
        }
        stopWatch.stop();
        log.debug("upload_file time used:" + stopWatch.getTotalTimeMillis() + "ms");
        if (uploadResults == null) {
            log.warn("upload file fail, error code:" + storageClient.getErrorCode());
            return null;
        }
        String groupName = uploadResults[0];
        String remoteFileName = uploadResults[1];
        log.debug("upload file successfully!!!" + "group_name:" + groupName + ", remoteFileName:" + " " + remoteFileName);
        return uploadResults;
    }

    /**
     * 根据groupName和文件名获取文件信息。
     *
     * @param groupName      组名
     * @param remoteFileName 文件名称
     * @return 文件信息
     */
    public FileInfo getFile(String groupName, String remoteFileName) {
        try {
            storageClient = new StorageClient(trackerServer, storageServer);
            return storageClient.get_file_info(groupName, remoteFileName);
        } catch (IOException e) {
            log.warn("IO Exception: Get File from Fast DFS failed", e);
            //todo 加入系统异常
        } catch (Exception e) {
            log.warn("Non IO Exception: Get File from Fast DFS failed", e);
            //todo 加入系统异常
        }
        return null;
    }

    /**
     * 根据groupName和文件名下载文件。
     *
     * @param groupName      组名
     * @param remoteFileName 文件名称
     * @return 文件数据流
     */
    public InputStream downFile(String groupName, String remoteFileName) {
        try {
            storageClient = new StorageClient(trackerServer, storageServer);
            byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
            InputStream ins = new ByteArrayInputStream(fileByte);
            return ins;
        } catch (IOException e) {
            log.debug("IO Exception: Get File from Fast DFS failed", e);
        } catch (Exception e) {
            log.debug("Non IO Exception: Get File from Fast DFS failed", e);
        }
        return null;
    }

    /**
     * 根据groupName和文件名删除文件。
     *
     * @param groupName      组名
     * @param remoteFileName 文件名称
     */
    public void deleteFile(String groupName, String remoteFileName)
            throws Exception {
        storageClient = new StorageClient(trackerServer, storageServer);
        int i = storageClient.delete_file(groupName, remoteFileName);
        log.debug("delete file " + remoteFileName + "successfully!!!" + i);
    }

    public String getTrackerUrl() throws IOException {
        return "http://" + trackerServer.getInetSocketAddress().getHostString() + ":" + ClientGlobal.getG_tracker_http_port() + "/";
    }
}
